#include "bp_intf.h"
#include "log/zlog.hh"
#include "rtdev/rtdev.h"
#include "rtbus/rtbus.h"
#include "jkutil/configparser.h"

rtdev::JkBpItf::JkBpItf()
{
    bp_id = 0;
    bp_status_ = {};
    bp_cmd_ = {};
}
int rtdev::JkBpItf::set_bp_logo_color(BpColor color)
{
    bp_cmd_.bp_rgb_logol_color = color;
    return 0;
}
int rtdev::JkBpItf::set_bp_logo_brightness(uint8_t data)
{
    bp_cmd_.bp_rgb_logol_brightness = data;
    return 0;
}
int rtdev::JkBpItf::set_bp_lock_color(BpColor color)
{
    bp_cmd_.bp_rgb_lock_color = color;
    return 0;
}
int rtdev::JkBpItf::set_bp_lock_brightness(uint8_t data)
{
    bp_cmd_.bp_rgb_lock_brightness = data;
    return 0;
}
int rtdev::JkBpItf::set_bp_beep(uint8_t data)
{
    bp_cmd_.bp_beep = data;
    return 0;
}

rtdev::ButtonPanelItf::ButtonPanelItf()
{
    sim_flag_ = 0;
    alive_watchdog_ = 0;
    alive_flag_ = false;
    last_alive_cnt_ = -1;
    bus_id_ = 1;
}

void rtdev::ButtonPanelItf::check_alive()
{
    bool alive = false;
    if (sim_flag_)
    {
        alive = true;
    }
    else
    {
        if (alive_watchdog_ <= 0)
        {
            alive = false;
        }
        else
        {
            alive_watchdog_--;
            alive = true;
        }
    }
    if (alive != alive_flag_)
    {
        zlog()->info("Device: {} is {}, sim={}", name(), alive ? "online" : "offline", sim_flag_);
        alive_flag_ = alive;
    }
}

int rtdev::ButtonPanelItf::keep_alive(int alive)
{
    if (last_alive_cnt_ != alive)
    {
        last_alive_cnt_ = alive;
        alive_watchdog_ = 1000;
        return 0;
    }
    return -1;
}
bool rtdev::ButtonPanelItf::is_alive() { return false; }
bool rtdev::ButtonPanelItf::is_sim() { return sim_flag_ == 1; }

int rtdev::ButtonPanelItf::init(const char* cfgfile)
{
    Util::ConfigParser cfg(cfgfile);
    cfg.get("bp.bus", bus_id_);
    int sflag = 0;
    cfg.get("bp.sim", sflag);
    sim_flag_ = sflag;

    return 0;
}
int rtdev::ButtonPanelItf::boot()
{
    auto bus = rtbus::BusMgr::get()->bus("scbbus");
    if (!bus)
        return -1;
    bus->config_rxpdo(BP_STATUS_R, 8);  //PDO
    bus->config_txpdo(BP_STATUS_W, 8);

    //NO SDO for bp device
    bus_ = bus;

    // todo 判定启动成功？

    return 0;
}

int rtdev::ButtonPanelItf::set_send_data(int busid)
{
    check_alive();
    if (!bus_)
        return -1;

    uint8_t data[8] = {0};
    data[0] = bp_.bp_cmd_.bp_beep;
    data[1] = static_cast<uint8_t>(bp_.bp_cmd_.bp_rgb_lock_color);
    data[2] = bp_.bp_cmd_.bp_rgb_lock_brightness;
    data[3] = static_cast<uint8_t>(bp_.bp_cmd_.bp_rgb_logol_color);
    data[4] = bp_.bp_cmd_.bp_rgb_logol_brightness;
    data[5] = bp_.bp_cmd_.heartbeat;
    bus_->set_txpdo_data(BP_STATUS_W, data);

    return 0;
}
int rtdev::ButtonPanelItf::get_recv_data(int busid)
{
    if (!bus_)
        return -1;

    uint8_t data[8] = {0};
    auto alive_cnt = bus_->get_rxpdo_data(BP_STATUS_R, data);
    if (keep_alive(alive_cnt))
    {
        return -1;
    }
    bp_.bp_status_.bp_beep = data[0];
    bp_.bp_status_.key_buffer = data[1];
    bp_.bp_status_.bp_rgb_lock_color = static_cast<rtdev::BpColor>(data[2]);
    bp_.bp_status_.bp_rgb_lock_brightness = data[3];
    bp_.bp_status_.bp_rgb_logol_color = static_cast<rtdev::BpColor>(data[4]);
    bp_.bp_status_.bp_rgb_logol_brightness = data[5];
    bp_.bp_status_.heartbeat = data[6];
    return 0;
}
